package main

import (
	"fmt"
	"log"
	"sync"
)

func main() {
	//testMap()
	//goMap()
	testMap20200718()
}

func testMap20200718() {
	// 1、对于map 进行了声明
	var map1 map[string]interface{}
	// 2、 创建了一个map2 的实例
	map2 := make(map[string]string)
	// 3、创建map3 实例并赋值
	map3 := map[string]interface{}{
		"1": "one",
		"2": "two",
	}
	fmt.Println(map1, "\t", map1 == nil)
	fmt.Println(map2, "\t", map2 == nil)
	fmt.Println(map3, "\t", map3 == nil)

	map1 = make(map[string]interface{})
	map1["heelo"] = "world"
	fmt.Println(map1, "\t", map1 == nil)

	//获取数据的时候，当对应的key 不出来的时候 获取的数据指的 对应数据类型的0值
	val := map2["th"]
	fmt.Printf("String对应的0值=%v", val)
	v, ok := map2["wo"]
	if ok == true {
		fmt.Println(v)
	} else {
		fmt.Printf("不存在对应的key %v\n", v)
	}
	map2["key1"] = "age =26"
	fmt.Printf("map2=%v \n", map2)
	delete(map2, "key1")
	fmt.Printf("map2=%v \n", map2)
	map2["ruihuan"] = "女"
	map2["ruixule"] = "男"

	//遍历map
	for key, val := range map2 {
		fmt.Printf("key :%v,val:%v \n", key, val)
	}
}

//map和读写锁并用保障map 的线程安全
func goMap() {
	//声明一个map
	m := make(map[string]interface{})
	//声音一个等待组
	var wg sync.WaitGroup
	//声明一个读写锁
	var rw sync.RWMutex
	wg.Add(20)
	for i := 0; i < 20; i++ {
		go func(j int) {
			//每个线程写之前上锁
			rw.Lock()
			m[fmt.Sprintf("key %d", j)] = fmt.Sprintf("val %d", j)
			//写完后释放锁
			rw.Unlock()
			wg.Done()
		}(i)
	}
	wg.Wait()
	//遍历map的结果
	for k, v := range m {
		fmt.Printf("key=%s val=%v\n", k, v)
	}
}

//线程安全map
func syncMap() {
	var m sync.Map
	//存入k v
	m.Store("rxl", 23)
	m.Store(34, "hello")
	m.Store(2, 23)
	//通过k 获取v
	if v, ok := m.Load(34); ok == true {
		log.Println(v)
		fmt.Printf("%#v \n", v)
	}
	//遍历所有的k v
	m.Range(func(k, v interface{}) bool {
		log.Println("before", k, v)
		return true
	})
	//删除
	m.Delete(2)
	m.Range(func(k, v interface{}) bool {
		log.Println("after", k, v)
		return true
	})
}

//非线程安全map
func testMap() {
	m := make(map[string]interface{})
	m["first"] = 1
	m["secidn"] = 2
	m["three"] = 3
	m["four"] = "ruixule"
	log.Println(m)
	delete(m, "three")
	log.Println(m)
}

func mapTest() {
	m := make(map[string]int)
	m["芮旭乐"] = 36
	m["芮欢"] = 23
	for k, v := range m {
		log.Println("k=%v,v=%v", k, v)
	}
	m["芮远路"] = 50
	age := m["芮旭乐"]
	log.Println(age)
	for k, v := range m {
		log.Println("k=%v,v=%v", k, v)
	}
	log.Println("delete value")
	delete(m, "芮远路")
	for k, v := range m {
		log.Println("k=%v,v=%v", k, v)
	}
	log.Println()
}
